﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharpAlgorithm
{
    class ChildrenWithHat
    {
        public ChildrenWithHat()
        {
            int testCount = Int32.Parse(TestConsole.ReadLine());

            for (int testCase = 1; testCase <= testCount; testCase++)
            {
                string[] input = TestConsole.ReadLine().Split(' ');
                int blackCaps = Int32.Parse(input[0]);
                int whiteCaps = Int32.Parse(input[1]);
                int childrens = Int32.Parse(input[2]);
                int iknow = Int32.Parse(input[3]);
                
                long result = 0;
                int forward = childrens - (iknow);
                int forwardBlackMin;
                int forwardWhiteMin;
                for (int i = 1; i < iknow; i++)
                {
                    forwardBlackMin = blackCaps - (i - 1);
                    forwardWhiteMin = whiteCaps - (i - 1);
                    result -= GetCaseCount(childrens, i, forwardBlackMin, forwardWhiteMin, blackCaps, whiteCaps);
                }
                forwardBlackMin = Math.Min(blackCaps - (iknow - 1), forward);
                forwardWhiteMin = Math.Min(whiteCaps - (iknow - 1), forward);
                result += GetCaseCount(childrens, iknow, forwardBlackMin, forwardWhiteMin, blackCaps, whiteCaps);
                
                //경우의 수
                
                Console.WriteLine("Case #" + testCase + ": " + result);

            }
        }
        private long GetCaseCount(int total, int index, int black, int white, int blackCaps, int whiteCaps)
        {
            int frontCount = total - index;
            //앞쪽의 경우의 수
            long caseBlack = 0;
            if (black > 0)
            {
                caseBlack = Factorial(frontCount, frontCount - black + 1) / Factorial(black, 1);
            }
            long caseWhite = 0;
            if (white > 0)
            {
                caseWhite = Factorial(frontCount, frontCount - white + 1) / Factorial(white, 1);
            }
            //뒤쪽
            long backBlack = 1;
            long backWhite = 1;
            if (index > 1)
            {
                int back = total - index + 1;
                int restBlack = blackCaps - black;
                int restWhite = whiteCaps - (frontCount - black);
                if (restBlack > 0 && restWhite > 0)
                {
                    int min = Math.Min(restBlack, restWhite);
                    int max = Math.Max(restBlack, restWhite);
                    for (int i = 0; i <= min; i++)
                    {
                        backBlack += Factorial(back, i) / (Factorial(i, 0) * Factorial(max - i, 0));
                    }
                }
                restWhite = whiteCaps - white;
                restBlack = blackCaps - (frontCount - white);
                if (restBlack > 0 && restWhite > 0)
                {
                    int min = Math.Min(restBlack, restWhite);
                    int max = Math.Max(restBlack, restWhite);
                    for (int i = 0; i <= min; i++)
                    {
                        backWhite += Factorial(back, i) / (Factorial(i, 0) * Factorial(max - i, 0));
                    }
                }
            }
            
            return (caseBlack * backBlack) + (caseWhite * backWhite);
        }
        private long Factorial(int start, int end)
        {
            if (start == 0 && end == 0) return 1;
            if (end > start) return 0;
            long result = start;
            for (int i = start - 1; i >= end; i--)
            {
                result *= i;
            }
            return result;
        }
    }
}
